package cn.org.donald.sensitive;

import cn.org.donald.sensitive.model.FactoryEnum;
import cn.org.donald.sensitive.model.FindStringRegex;
import cn.org.donald.sensitive.model.KeyWordPositionListener;
import cn.org.donald.sensitive.model.PdfMatchItem;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Donald
 * @since 2023-11-10 18:00:22
 **/
public class ReplaceTest {
    public static void main(String[] args) throws IOException, DocumentException {
        List<String> list = new ArrayList<>();
        list.add(FindStringRegex.MOBILE_PHONE);
        String src = "D:\\develop\\sensitive\\1.pdf";
        String desc = "D:\\develop\\sensitive\\1-new.pdf";
        Path filePath = Paths.get(src);
        List<String> sensitiveString = FactoryEnum.getInstance(filePath).getSensitiveString(list);
        String replacement = "***********";
        // TODO 先找到文字位置
        PdfReader pdfReader = new PdfReader(src);
        List<PdfMatchItem> matchItem = getMatchItem(pdfReader, sensitiveString);
        Map<Integer, List<PdfMatchItem>> map = matchItem.stream().collect(Collectors.groupingBy(PdfMatchItem::getCurrentPage));
        // TODO 遍历每一页去修改
        PdfStamper pdfStamper = new PdfStamper(pdfReader, Files.newOutputStream(Paths.get(desc)));
        for (String keyword : sensitiveString) {
            map.forEach((k, v) -> {
                for (PdfMatchItem pdfMatchItem : v) {
                    PdfContentByte overContent = pdfStamper.getOverContent(k);
                    Float x = pdfMatchItem.getX();
                    Float y = pdfMatchItem.getY();
                    Float fontHeight = pdfMatchItem.getFontHeight();
                    Float fontWidth = pdfMatchItem.getFontWidth();
                    overContent.saveState();
                    overContent.setColorFill(BaseColor.WHITE);
                    int length = keyword.length();
                    StringBuilder replace = new StringBuilder();
                    for (int i = 0; i < length; i++) {
                        replace.append("*");
                    }
                    overContent.rectangle(x, y, fontWidth * length, fontWidth + 2);
                    overContent.fill();
                    overContent.restoreState();
                    // 开始写入文本
                    /*overContent.beginText();
                    try {
                        Font font = new Font(
                                BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED),
                                fontHeight,
                                Font.BOLD
                        );
                        overContent.setFontAndSize(font.getBaseFont(), 7);
                        overContent.setTextMatrix(x, y + fontWidth/10 + 0.5f);
                        overContent.showText(replace.toString());
                        overContent.endText();
                    } catch (DocumentException | IOException e) {
                        e.printStackTrace();
                    }*/
                }
            });
        }

        pdfStamper.close();
        pdfReader.close();
    }


    private static List<PdfMatchItem> getMatchItem(PdfReader reader, List<String> targetStringList) throws IOException {
        List<PdfMatchItem> list = new ArrayList<>();
        int numberOfPages = reader.getNumberOfPages();
        for (int i = 1; i <= numberOfPages; i++) {
            Rectangle rectangle = reader.getPageSize(i);
            PdfReaderContentParser parse = new PdfReaderContentParser(reader);
            for (String keyword : targetStringList) {
                KeyWordPositionListener keyWordPositionListener = new KeyWordPositionListener(i, rectangle, keyword);
                parse.processContent(i, keyWordPositionListener);
                List<PdfMatchItem> keyWordItems = findKeyWordItems(keyWordPositionListener, keyword);
                keyWordItems.forEach(System.out::println);
                list.addAll(keyWordItems);
            }
        }
        return list;
    }


    private static List<PdfMatchItem> findKeyWordItems(KeyWordPositionListener listener, String keyword) {
        List<PdfMatchItem> allItems = listener.getAllItems();
        List<PdfMatchItem> matches = listener.getMatches();
        // 将一页中所有内容连接起来组成一个字符串
        StringBuilder allContent = new StringBuilder();
        for (PdfMatchItem pdfMatchItem : allItems) {
            allContent.append(pdfMatchItem.getContent());
        }
        String allText = allContent.toString();
        //一页组成的字符串没有关键词，直接return
        //第一种情况：关键词与块内容完全匹配的项,直接返回
        if (!allText.contains(keyword) || !matches.isEmpty()) {
            return matches;
        }
        //第二种情况：多个块内容拼成一个关键词，则一个一个来匹配，组装成一个关键词
        allContent = new StringBuilder();
        List<PdfMatchItem> tempItems = new ArrayList<>();
        for (PdfMatchItem item : allItems) {
            String content = item.getContent();
            if (keyword.contains(content)) {
                tempItems.add(item);
                allContent.append(content);
                // 如果暂存的字符串和关键字不再匹配时
                if (!keyword.contains(allContent.toString())) {
                    allContent = new StringBuilder(content);
                    tempItems.clear();
                    tempItems.add(item);
                } else if (allContent.toString().equalsIgnoreCase(keyword)) {
                    // 暂存的字符串和关键字正好匹配
                    matches.add(tempItems.get(0));
                    allContent = new StringBuilder();//清空暂存的字符串
                    tempItems.clear();
                }
            } else {
                // 如果找不到清空
                allContent = new StringBuilder();
                tempItems.clear();
            }
        }
        return matches;
    }
}
